#include "textureogl.h"

using std::string;
using namespace EPOC;

TextureOGL::TextureOGL()
{
	SetClassID(kCLASSID_TEXTURE_OGL);
	m_hTexture = 0;
}

TextureOGL::TextureOGL(GraphicsManager *pGraphicsManager) : Texture(pGraphicsManager)
{
	SetClassID(kCLASSID_TEXTURE_OGL);
	m_hTexture = 0;
}


TextureOGL::~TextureOGL()
{
	TextureOGL::Cleanup();
}

void TextureOGL::Cleanup()
{
	if(m_hTexture > 0)
		glDeleteTextures( 1, &m_hTexture );
}

bool TextureOGL::Initialize(string sName, string sFilePath, SDL_Surface *pSDLSurface, bool bExclusive, bool bEditable)
{
	if(Texture::Initialize(sName, sFilePath, bExclusive) == false)
		return false;

	//if(!pSDLSurface)
	//	return false;

	m_bEditable = bEditable;
	m_hTexture = BuildGLTexture(pSDLSurface, !IsEditable());
	
	if( IsEditable() )
		SetSDLSurface(pSDLSurface);

	return true;
}

bool TextureOGL::UpdateTexture()
{
	return RebuildGLTexture();
}

GLuint TextureOGL::BuildGLTexture(SDL_Surface *pSDLSurface, bool bRemove)
{
	if(!pSDLSurface)
		return 0;

	if(m_hTexture == 0)
		glGenTextures( 1, &m_hTexture );		// Have OpenGL generate a texture object handle for us

	// Bind the texture object
	glBindTexture( GL_TEXTURE_2D, m_hTexture );
 
	// Set the texture's stretching properties
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

	if( SDL_MUSTLOCK( pSDLSurface))
		if( SDL_LockSurface( pSDLSurface) > 0 )
			return 0;

			// Edit the texture object's image data using the information SDL_Surface gives us
			glTexImage2D( GL_TEXTURE_2D, 0, pSDLSurface->format->BytesPerPixel, pSDLSurface->w, pSDLSurface->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, pSDLSurface->pixels );
		
	if( SDL_MUSTLOCK( pSDLSurface))
		SDL_UnlockSurface( pSDLSurface );


	SetDimension(pSDLSurface->h, pSDLSurface->w);
	
	if(bRemove)
		SDL_FreeSurface(pSDLSurface);

	return m_hTexture;
}

bool TextureOGL::RebuildGLTexture()
{
	if(m_hTexture == 0)
		return false;

	if(!GetSDLSurface())
		return false;

	glBindTexture( GL_TEXTURE_2D, m_hTexture );
 
	// Set the texture's stretching properties
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

	if( SDL_MUSTLOCK( GetSDLSurface()))
		if( SDL_LockSurface( GetSDLSurface()) > 0 )
			return false;

	// Edit the texture object's image data using the information SDL_Surface gives us
	glTexImage2D( GL_TEXTURE_2D, 0, GetSDLSurface()->format->BytesPerPixel, GetSDLSurface()->w, GetSDLSurface()->h, 0, GL_BGRA, GL_UNSIGNED_BYTE,  GetSDLSurface()->pixels );

	if( SDL_MUSTLOCK( GetSDLSurface() ) )
		SDL_UnlockSurface( GetSDLSurface() );

	SetDimension(GetSDLSurface()->h, GetSDLSurface()->w);

	return true;
}